using System;
using System.Collections.Generic;
using System.Text;
using System.Web.UI.Adapters;
using System.Web.UI;
using System.IO;
using System.Web;
using Microsoft.SharePoint.Administration;
using System.Web.Caching;
using System.Text.RegularExpressions;

namespace CewpUriRewriter
{
    /// <summary>
    /// http://blogs.msdn.com/maximeb/archive/2008/12/23/fixing-absolute-urls-for-all-alternate-access-mappings-aam-of-content-editor-web-part-with-a-control-adapter.aspx
    /// http://msdn.microsoft.com/en-us/library/dd571480.aspx
    /// </summary>
    public class CewpAAMControlAdapter : ControlAdapter
    {
        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            // Render the content-output to a stringbuilder
            StringBuilder sb = new StringBuilder();
            HtmlTextWriter htw = new HtmlTextWriter(new StringWriter(sb));
            base.Render(htw);

            // Replace urls in the content-output
            string output = sb.ToString();
            List<Uri> alternateUrls = GetAlternateUrls();
            foreach (Uri alternateUrl in alternateUrls)
            {
                //The next code would also replace text with urls 
                //output = output.Replace(alternateUrl.ToString(), "/");

                Regex regex = new Regex("((?:href|src)=\")" + alternateUrl.ToString() + "([^\"]+\")");
                output = regex.Replace(sb.ToString(), "$1/$2");
            }

            // Write out the altered content-output
            writer.Write(output);
        }

        /// <summary>
        /// The key which will be used to cache the AlternateUrl-collection
        /// </summary>
        private const string ALTERNATEURLSCACHEKEY = "AlternateUrls";

        /// <summary>
        /// The duration for which the AlternateUrl-collection will be cached
        /// </summary>
        private TimeSpan ALTERNATEURLSCACHETIMESPAN = new TimeSpan(12, 0, 0);

        /// <summary>
        /// This method will retrieve the (cached) AlternateUrl-collection
        /// </summary>
        /// <returns>The AlternateUrl-collection</returns>
        private List<Uri> GetAlternateUrls()
        {
            List<Uri> alternateUrls = (List<Uri>)HttpContext.Current.Cache[ALTERNATEURLSCACHEKEY];
            if (alternateUrls == null)
            {
                alternateUrls = new List<Uri>();
                SPWebApplication webApp = SPWebApplication.Lookup( HttpContext.Current.Request.Url );
                foreach (SPAlternateUrl alternateUrl in webApp.AlternateUrls)
                {
                    alternateUrls.Add(alternateUrl.Uri);
                }
                
                HttpContext.Current.Cache.Add( ALTERNATEURLSCACHEKEY , alternateUrls, null, DateTime.Now.Add(ALTERNATEURLSCACHETIMESPAN) , Cache.NoSlidingExpiration, CacheItemPriority.Normal, null);
            }

            return alternateUrls;
        }

    }
}
